package com.general.app.wjgl.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import com.general.app.wjgl.dao.IFactorDao;
import com.general.app.wjgl.dao.IQuestionDao;
import com.general.app.wjgl.dao.ISurveyDao;
import com.general.app.wjgl.dao.entity.Factor;
import com.general.app.wjgl.dao.entity.Question;
import com.general.app.wjgl.dao.entity.QuestionOption;
import com.general.app.wjgl.dao.entity.Survey;
import com.general.app.wjgl.service.ISurveyService;
import com.general.app.wjgl.type.IsNotType;
import com.general.app.wjgl.type.QuestionType;
import com.general.common.exception.BusinessException;
import com.general.common.service.impl.BaseServiceImpl;
import com.general.utils.base.Constant;
import com.general.utils.base.UuidUtil;

/**
 * 问卷维护
 * @author Administrator
 *
 */
public class SurveyServiceImpl extends BaseServiceImpl<Survey, ISurveyDao> implements ISurveyService{

	private IFactorDao factorDao;
	private IQuestionDao questionDao;
	
	private Logger log = LoggerFactory.getLogger(ISurveyService.class);
	
	public void setFactorDao(IFactorDao factorDao) {
		this.factorDao = factorDao;
	}

	
	public void setQuestionDao(IQuestionDao questionDao) {
		this.questionDao = questionDao;
	}


	/*
	 * (non-Javadoc)
	 * @see com.general.app.wjgl.service.ISurveyService#saveSurveyDegin(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public boolean saveSurveyDegin(Survey s ,String surveyInfo) throws BusinessException {
		
		JSONObject surveyJson = JSONObject.fromObject(surveyInfo);
		
		String surveyId = (String) surveyJson.get("id");
		
		//删除该问卷下关联试题
		int d = dao.deleteRelevanceQuestion(surveyId);
		log.debug("删除问卷关联试题记录：{}条。",d);
		
		List<Map<String,?>> questionArray =  ((JSONArray)surveyJson.get("questionList"));
		List<Question> questionList = new ArrayList<Question>();
		int order = 1;
		for (Map<String,?> q : questionArray){
			
			String qId = UuidUtil.getInstance().getUniqID();
			
			Question question = new Question();
			question.setId(qId);
			question.setQuestion_order(String.valueOf(order));
			question.setName((String)q.get("name"));
			
			//试题类型
			String styleId = (String)q.get("style");
			question.setStyleId(getQuestionType(styleId));
			
			//是否必答
			String required = (String)q.get("required");
			question.setRequired(getIsNotType(required));
			
			//问卷因子
			String factorName = (String) q.get("factor");
			Factor factor = new Factor();
			if(factorName!=null && !"".equals(factorName.trim())){
				factor = factorDao.getFactorByName(factorName);
			}
			
			//特殊标记
			String speMark = (String) q.get("speMark");
			question.setSpeMark(getIsNotType(speMark));
			
			//最多选择项
			String selectCounts = String.valueOf(q.get("selectCounts"));
			question.setSelectCounts(selectCounts);
			
			//关键词
			String keyword = (String) q.get("keyword");
			question.setKeyword(keyword);
			
			if (factor == null){
				if(factorName!=null && !"".equals(factorName.trim())){
					factor = new Factor();
					factor.setId(UuidUtil.getInstance().getUniqID());
					factor.setName(factorName);
					factor.setUsedFlg(Constant.OPEN);
					factorDao.insert(factor);
				}
			}
			question.setFactor(factor);
			
			List<Map<String,String>> optionArray = (List<Map<String, String>>) q.get("optionList");
			List<QuestionOption> optionList = new ArrayList<QuestionOption>();
			
			//试题答案
			for (Map<String,String> o : optionArray){
				QuestionOption option = new QuestionOption();
				option.setName(o.get("name"));
				option.setContent(o.get("content"));
				option.setScore(o.get("score"));
				option.setQuestion(question);
				optionList.add(option);
			}
			
			question.setOptionList(optionList);
			
			boolean disExis = disposeExistsQuestion(question, surveyId ,order);
			order++;
			if (!disExis){
				questionList.add(question);
			}else{
				
			}
		}
		
		Survey survey = dao.getModel(surveyId);
		survey.setQuestionList(questionList);
		
		if (questionList.size() > 0){
			
			int q = dao.batchSaveQuestion(survey);
			log.debug("保存试题记录：{}条。",q);
			
			int z = dao.batchSaveSurveyQuestion(survey);
			log.debug("保存问卷与试题关系：{}条。",z);

			try{
				int i = dao.batchSaveQuestionOption(survey);
				log.debug("保存试题选项记录：{}条。",i);
			}catch (Exception e) {
				log.debug("保存答案记录：0条。");
			}
			
		}
		
		//更新问卷设计内容
		return dao.update(s) > 0;
	}

	
	
	//按试题类型查ID
	private String getQuestionType(String typeName) {
		
		QuestionType[] questions = QuestionType.values();
		
		for (QuestionType q : questions){
			if (q.getName().equals(typeName)){
				return q.getId();
			}
		}
		return null;
	}
	
	
	//是否必答名称转ID
	private String getIsNotType(String typeName) {
		
		IsNotType[] types = IsNotType.values();
		
		for (IsNotType q : types){
			if (q.getName().equals(typeName)){
				return q.getId();
			}
		}
		return null;
	}
	
	//处理已经存在的试题（存在：保存试题与问卷的关系 返回true，不存在：返回false）
	private boolean disposeExistsQuestion(Question question,String surveyId,int order){
		
		// 按试题名称、试题类型、所属问卷因子查询是否有已存在试题，不存在 return false;
		List<Question> qList = questionDao.getExistsQuestion(question);
		if (qList == null || qList.isEmpty()){
			return false;
		}
		//列出试题选项，按试题ID，选项名称、选项内容、选项分值 与 已存在试题进行比较
		List<QuestionOption> qoList = question.getOptionList();
		for (Question q : qList){
			
			List<QuestionOption> oList = q.getOptionList();
			//比较试题选项是否一致
			boolean compareResult = compareOptionList(qoList, oList);
			
			if (compareResult){
				//存在，保存问卷与试题关系.结束循环
				Map<String,String> map = new HashMap<String,String>();
				map.put("surveyId", surveyId);
				map.put("questionId", q.getId());
				map.put("order", String.valueOf(order));
				dao.saveSurveyQuestion(map);
				
				log.debug("保存已存在试题（试题ID：{}）与问卷（问卷ID：{}）之间的关系 。",q.getId(),surveyId);
				return true;
			}
		}
		
		return false;
	}
	
	
	//比较试题选项是否一致
	private boolean compareOptionList(List<QuestionOption> qoList , List<QuestionOption> oList){
		
		//全空判断
		if ((qoList == null && oList == null) || (qoList.isEmpty() && oList.isEmpty()))
			return true;
		//其中一项为空判断
		if ((qoList == null || qoList.isEmpty()) || (oList == null || oList.isEmpty()))
			return false;
		//长度判断
		if (qoList.size() != oList.size())
			return false;
		
		//循环比较具体选项
		for (int i = 0 , j = qoList.size() ; i < j ; i++){
			QuestionOption qoOption = qoList.get(i);
			QuestionOption oOption = oList.get(i);
			
			if (!qoOption.toString().equals(oOption.toString())){
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * 复制问卷
	 * @param surveyId
	 * @return
	 */
	public boolean copySurvey(String surveyId){
		
		// 复制问卷基本信息
		Survey model = dao.getModel(surveyId);
		String id = UUID.randomUUID().toString();
		model.setId(id);
		model.setName("复制"+model.getName());
		boolean bolFlg = dao.insert(model) > 0 ? true : false ;
		
		// 复制问卷和试题关系
		if(bolFlg){
			//存在，保存问卷与试题关系.结束循环
			Map<String,String> map = new HashMap<String,String>();
			map.put("surveyId", id);
			map.put("surveyIdOld", surveyId);			
			dao.copySurveyQuestion(map);
		}	
		
		return bolFlg;
	}
}
